/*
 * @Author:hui.he
 * @Date: 2021-06-18 09:23:32
 * @LastEditTime: 2021-06-18 15:50:53
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: \yhjr-jrsdk-h5\src\common\service\httpService\index.js
 */

import CONFIG from "./config";

//定义用来存储拦截请求和拦截响应结果的处理函数集合
let interceptors_req = [],
	interceptors_res = [];

/**
 * @msg:
 * @param {*} type 请求类型
 * @param {*} objs 参数对象
 * @return {*}
 */
function HTTPSend(type, objs) {
	//初始公共配置
	let base = {
		url: objs.url || "", //地址
		headers: {
			//请求头
			Accept: "application/json",
			"Content-Type": "application/json"
		},
		timeout: objs.timeout || CONFIG.HTTP_TIMEOUT, //超时时间
		params: objs.params || {}, //请求参数
		is_ignore: objs.is_ignore || false, //是否自己处理错误
		is_download: objs.is_download || false, //是否下载
		is_uploadFile: objs.is_uploadFile || false //是否上传文件
	};
	//拦截器
	interceptors_req.forEach(interceptors => {
		base = interceptors(base);
	});
	console.log("请求拦截处理后base", base);
	let url = base.url;
	let fetchOpts = {
		method: type,
		headers: base.headers
	};
	let req = base.params;
	let body = {};
	for (let i in req) {
		if (typeof req[i] == "function") {
			body[i] = req[i]();
		} else {
			body[i] = req[i];
		}
	}

	//get请求
	if (type === "GET") {
		if (body && JSON.stringify(body) !== "{}") {
			let searchArray = [];
			Object.keys(body).forEach(key => searchArray.push(key + "=" + body[key]));
			if (!url.match(/\?/)) {
				url += "?" + searchArray.join("&");
			} else {
				url += "&" + searchArray.join("&");
			}
		}
	}

	//post请求
	if (type === "POST") {
		if (fetchOpts.headers["Content-Type"] === "application/json") {
			fetchOpts.body = JSON.stringify(body);
		} else if (base.is_uploadFile) {
			let formData = new FormData();
			for (let key in body) {
				formData.append(key, body[key]);
			}
			fetchOpts.body = formData;
		} else {
			let formData = "";
			for (let param in body) {
				formData += "&" + param + "=" + body[param];
			}
			fetchOpts.body = formData.substring(1);
		}
	}

	const requestPromise = new Promise(function (resolve, reject) {
		if (!fetch) {
			return Promise.reject({ errNo: 0, message: `不支持fetch api` });
		}
		fetch(url, fetchOpts)
			.then(response => {
				//下载
				if (base.is_download) {
					response.blob().then(blob => {
						let filename = `filename.xls`;
						if (window.navigator.msSaveOrOpenBlob) {
							navigator.msSaveBlob(blob, filename); //兼容ie10
						} else {
							let a = document.createElement("a");
							document.body.appendChild(a); //兼容火狐，将a标签添加到body当中
							let url = window.URL.createObjectURL(blob); // 获取 blob 本地文件连接 (blob 为纯二进制对象，不能够直接保存到磁盘上)
							a.href = url;
							a.download = filename;
							a.target = "_blank"; // a标签增加target属性
							a.click();
							a.remove(); //移除a标签
							window.URL.revokeObjectURL(url);
						}
					});
				} else if (response.ok) {
					if (fetchOpts.headers["Accept"] == "text/plain") {
						return response.text();
					}
					return response.json();
				} else {
					//请求错误
					return Promise.reject(CONFIG.HTTP_001_REQUEST_ERROR);
				}
			})
			.then(res => {
				resolve(res);
			})
			.catch(res => {
				//响应错误
				if (res.errNo) {
					reject(res);
				} else {
					reject(CONFIG.HTTP_002_RESPONSE_ERROR);
				}
			});
	});
	const timerPromise = new Promise((resolve, reject) => {
		//请求超时
		setTimeout(() => {
			reject(CONFIG.HTTP_003_REQUEST_TIMEOUT);
		}, base.timeout * 1000);
	});
	return Promise.race([requestPromise, timerPromise]).then(
		res => {
			console.log(`请求成功`, `接口地址：${url}`, `参数`, base, `结果`, res);
			//拦截器
			interceptors_res.forEach(interceptors => {
				res = interceptors(res);
			});
			return Promise.resolve(res);
		},
		res => {
			//如果需要单独做错误处理；
			if (base.is_ignore) {
				return Promise.resolve(res);
			}
			//拦截器
			interceptors_res.forEach(interceptors => {
				res = interceptors(res);
			});
			return Promise.reject(res);
		}
	);
}
function HTTPGet(objs) {
	return HTTPSend("GET", objs);
}
function HTTPPost(objs) {
	return HTTPSend("POST", objs);
}
let HTTP = {
	post: HTTPPost,
	get: HTTPGet,
	interceptors: {
		request: {
			use: function (callback) {
				interceptors_req.push(callback);
			}
		},
		response: {
			use: function (callback) {
				interceptors_res.push(callback);
			}
		}
	}
};
export default HTTP;
require("./interceptors.js");
